<?php 
declare(strict_types=1);
namespace App\Service;

 use App\Constants\ErrorCode;
 use App\Dao\AdminLogDao;
 use App\Dao\AreaDao;
 use App\Dao\ChannelAreaDao;
 use App\Dao\ChannelDao;
 use App\Dao\RechargeAmountChannelDao;
 use App\Dao\RechargeAmountDao;
 use App\Exception\BusinessException;
 use App\Utils\ServerUtil;

 class ChannelService
 {
     /**
      * 获取渠道列表
      * @param $page
      * @param $pageSize
      * @param string $name
      * @return array
      */
     public function list($page, $pageSize, $name='')
     {

         $where = ['is_del' => 1];
         if($name){
             $where[] = ['name','like' ,'%'.$name.'%'];
         }

         $data = make(ChannelDao::class)->getListPage($where, $page, $pageSize);
         if(!empty($data['list'])){
             foreach($data['list'] as $k => $v){
                 $data['list'][$k]['start_data'] = empty($v['start_time'])?'':date('Y-m-d H:i',$v['start_time']);
                 $data['list'][$k]['add_data'] = empty($v['add_time'])?'':date('Y-m-d H:i',$v['add_time']);
                 unset($data['list'][$k]['start_time']);
                 unset($data['list'][$k]['add_time']);
                 unset($data['list'][$k]['is_del']);
             }
         }

         return $data;

     }

     /**
      * 获取全部渠道
      * @return array
      */
     public function all()
     {
         return make(ChannelDao::class)->getAll(['id','name']);
     }

     /**
      * 添加渠道
      * @param $insert
      * @return int
      */
     public function add($insert)
     {
         $apiInfoArray = @json_decode($insert['api_info'],true);
         if(empty($apiInfoArray['api_name'])){
             throw new BusinessException(ErrorCode::ERR_SERVER, '渠道api信息参数不完整');
         }

         $insert['start_time'] = strtotime($insert['start_time']);
         $insert['id'] = make(ChannelDao::class)->add($insert);
         if(empty($insert['id'])){
             throw new BusinessException(ErrorCode::ERR_SERVER, '网络繁忙,请重试');
         }
         make(AdminLogDao::class)->addLog('添加渠道：'.json_encode($insert));
         return $insert['id'];
     }

     /**
      * 获取渠道信息
      * @param $id
      * @return array
      */
     public function get($id)
     {
         $info = make(ChannelDao::class)->findById($id, ['*'], true);
         if(empty($info)){
             throw new BusinessException(ErrorCode::ERR_BUESSUS, '渠道不存在');
         }

         $info['start_data'] = empty($info['start_time'])?'':date('Y-m-d H:i:s',$info['start_time']);
         $info['add_data'] = empty($info['add_time'])?'':date('Y-m-d H:i:s',$info['add_time']);
         return $info;
     }


     /**
      * 更新渠道信息
      * @param $update
      * @return int
      */
     public function edit($update)
     {
         $apiInfoArray = @json_decode($update['api_info'],true);
         if(empty($apiInfoArray['api_name'])){
             throw new BusinessException(ErrorCode::ERR_SERVER, '渠道api信息参数不完整');
         }

         $channelDao = make(ChannelDao::class);
         $info = $channelDao->findById($update['id'], ['*'], true);
         if(empty($info)){
             throw new BusinessException(ErrorCode::ERR_BUESSUS, '渠道不存在');
         }

         make(AdminLogDao::class)->addLog('编辑渠道：编辑前：'.json_encode($info).'  编辑后：'.json_encode($update));
         unset($update['id']);
         $update['start_time'] = strtotime($update['start_time']);
         return $channelDao->updateById($info['id'], $update);
     }

     /**
      * 删除渠道
      * @param $id
      * @return int
      */
     public function del($id)
     {
         $channelDao = make(ChannelDao::class);
         $info = $channelDao->findById($id, ['id'], true);
         if(empty($info)){
             throw new BusinessException(ErrorCode::ERR_BUESSUS, '渠道不存在');
         }
         make(AdminLogDao::class)->addLog('删除渠道：'.json_encode($info));
         return $channelDao->updateById($id, ['is_del'=>2]);
     }

     /**
      * 编辑渠道备注
      * @param $id
      * @param $remark
      * @return int
      */
     public function remark($id, $remark)
     {
         $channelDao = make(ChannelDao::class);
         $info = $channelDao->findById($id, ['id','remark'], true);
         if(empty($info)){
             throw new BusinessException(ErrorCode::ERR_BUESSUS, '渠道不存在');
         }
         make(AdminLogDao::class)->addLog('编辑渠道备注：编辑前：'.json_encode($info).'  编辑后：'.$remark);
         return $channelDao->updateById($id, ['remark'=>$remark]);
     }

     /**
      * 获取渠道地区列表配置
      * @param $id
      * @return array[]
      */
     public function areaList($id)
     {
         $data = make(ChannelAreaDao::class)->getChannelAllArea($id);
         $list = ['fast' => [], 'slow' => []];
         $typeArray = [1=>'fast',2=>'slow'];
         $operatorTypeArray =  [1=>'mobile',2=>'telecom',3=>'unicom'];
         if(!empty($data)){
             foreach ($data as $k => $v) {
                 $list[$typeArray[$v['type']]][$operatorTypeArray[$v['operator_type']]][$v['province_id']][] = [
                     'id' => $v['id'],
                     'city_id' => $v['city_id']

                 ];
             }
         }
         unset($data);
         return $list;
     }

     /**
      * 新增/删除渠道地区配置
      * @param $id
      * @param $type
      * @param $operatorType
      * @param $provinceId
      * @param $cityId
      * @return bool
      */
     public function areaEdit($id, $type, $operatorType, $provinceId, $cityId)
     {
         $channelDao = make(ChannelDao::class);
         $channelAreaDao = make(ChannelAreaDao::class);

         $info = $channelDao->findById($id, ['*'], true);
         if(empty($info)){
             throw new BusinessException(ErrorCode::ERR_BUESSUS, '渠道不存在');
         }

         $typeArray = ['fast'=>1, 'slow'=>2];
         $operatorTypeArry = ['mobile'=>1, 'telecom'=>2, 'unicom'=>3];

         $type = $typeArray[$type];
         $operatorType = $operatorTypeArry[$operatorType];

         if(!make(AreaDao::class)->findByWhere(['parent_id'=>$provinceId,'id'=>$cityId,'level_type'=>2], ['id'])){
             throw new BusinessException(ErrorCode::ERR_BUESSUS, '不支持该城市');
         }

         //判断删除还是新增
         $where = [
             'channel_id' => $id,
             'type' => $type,
             'operator_type' => $operatorType,
             'province_id' => $provinceId,
             'city_id' => $cityId,
             'is_del' => 1,
         ];
         $channelAreaInfo = $channelAreaDao->findByWhere($where);
         if($channelAreaInfo){//删除
             $deleteStatus =  $channelAreaDao->del(['id'=>$channelAreaInfo['id']]);
             //更新渠道支持类型
             if($deleteStatus && $info['type'] - $type >= 0 && !$channelAreaDao->findByWhere(['channel_id'=>$id,'type' => $type,'is_del' => 1])){
                 $channelDao->updateById($id, ['type'=>$info['type'] - $type]);
                 ServerUtil::info( '新增/删除渠道地区配置', [
                     'path'=>'/admin/channel_areaEdit',
                     'parameter'=>['channel_id'=>$id,'status'=>2,'where'=>$where],
                     'info'=> $info,
                 ]);
             }
             //添加管理员操作日记
             make(AdminLogDao::class)->addLog('删除渠道地区配置：'.json_encode($where));
         }else{//添加
             //更新渠道支持类型
             $typeStatus = $channelAreaDao->findByWhere(['channel_id'=>$id,'type' => $type,'is_del' => 1]);
             if(!$typeStatus && $channelAreaDao->add($where) && $info['type'] + $type < 4){
                 $channelDao->updateById($id, ['type'=>$info['type'] + $type]);
                 ServerUtil::info( '新增/删除渠道地区配置', [
                     'path'=>'/admin/channel_areaEdit',
                     'parameter'=>['channel_id'=>$id,'status'=>1,'where'=>$where],
                     'info'=> $info,
                 ]);
             }
             //添加管理员操作日记
             make(AdminLogDao::class)->addLog('新增渠道地区配置：'.json_encode($where));
         }

         return true;

     }


     /**
      * 批量编辑渠道地区配置（市级全选/全不选）
      * @param $channelId
      * @param $type
      * @param $operatorType
      * @param $provinceId
      * @param $status
      * @return bool
      */
     public function areaBatchEdit($channelId, $type, $operatorType, $provinceId, $status=1)
     {

         $channelDao = make(ChannelDao::class);
         $channelAreaDao = make(ChannelAreaDao::class);
         $areaDao = make(AreaDao::class);

         $info = $channelDao->findById($channelId, ['*'], true);
         if(empty($info)){
             throw new BusinessException(ErrorCode::ERR_BUESSUS, '渠道不存在');
         }

         $typeArray = ['fast'=>1, 'slow'=>2];
         $operatorTypeArry = ['mobile'=>1, 'telecom'=>2, 'unicom'=>3];

         $type = $typeArray[$type];
         $operatorType = $operatorTypeArry[$operatorType];

         $cityList = $areaDao->getList(['parent_id'=>$provinceId,'level_type'=>2], ['id']);
         if(empty($cityList)){
             throw new BusinessException(ErrorCode::ERR_BUESSUS, '不支持该省');
         }

         $where = [
             'channel_id' => $channelId,
             'type' => $type,
             'operator_type' => $operatorType,
             'province_id' => $provinceId,
             'is_del' => 1,
         ];

         if($status == 1){//全选
             //渠道支持类型
             $channelAreaInfo = $channelAreaDao->findByWhere(['channel_id'=>$channelId,'type' => $type,'is_del' => 1]);
             //查询已存在地区
             $channelCityList = $channelAreaDao->findByWhere($where, 'city_id');
             $channelAreaInfo = json_decode(json_encode($channelAreaInfo), true);
             $channelCityList = json_decode(json_encode($channelCityList), true);
             $channelCityList = empty($channelCityList) ? [] : array_column($channelCityList, 'city_id');
             $cityList = array_column($cityList, 'id');
             $resultCityList = array_diff($cityList, $channelCityList);
             //新增地区
             foreach ($resultCityList as $value){
                 $where['city_id'] = $value;
                 $channelAreaDao->add($where);
             }

             if(!$channelAreaInfo && $info['type'] + $type < 4){
                 $channelDao->updateById($channelId, ['type'=>$info['type'] + $type]);
                 ServerUtil::info( '批量编辑渠道地区配置', [
                     'path'=>'/admin/channel_areaBatchEdit',
                     'parameter'=>['channel_id'=>$channelId,'status'=>$status],
                     'info'=> $info,
                 ]);
             }
             //添加管理员操作日记
             make(AdminLogDao::class)->addLog('渠道批量新增省级下全部地区：'.json_encode($where));

         }else{//全不选
             $deleteStatus =  $channelAreaDao->del($where);
             //更新渠道支持类型
             if($deleteStatus && $info['type'] - $type >= 0 && !$channelAreaDao->findByWhere(['channel_id'=>$channelId,'type' => $type,'is_del' => 1])){
                 $channelDao->updateById($channelId, ['type'=>$info['type'] - $type]);
                 ServerUtil::info( '批量编辑渠道地区配置', [
                     'path'=>'/admin/channel_areaBatchEdit',
                     'parameter'=>['channel_id'=>$channelId,'status'=>$status],
                     'info'=> $info,
                 ]);
             }
             //添加管理员操作日记
             make(AdminLogDao::class)->addLog('渠道批量删除省级下全部地区：'.json_encode($where));
         }

         return true;

     }


     /**
      * 批量编辑渠道地区配置（省级级全选/全不选）
      * @param $channelId
      * @param $type
      * @param $operatorType
      * @param int $status
      * @return bool
      */
     public function areaBatchAllEdit($channelId, $type, $operatorType, $status=1)
     {

         $channelDao = make(ChannelDao::class);
         $channelAreaDao = make(ChannelAreaDao::class);
         $areaDao = make(AreaDao::class);

         $info = $channelDao->findById($channelId, ['*'], true);
         if(empty($info)){
             throw new BusinessException(ErrorCode::ERR_BUESSUS, '渠道不存在');
         }


         $typeArray = ['fast'=>1, 'slow'=>2];
         $operatorTypeArry = ['mobile'=>1, 'telecom'=>2, 'unicom'=>3];

         $type = $typeArray[$type];
         $operatorType = $operatorTypeArry[$operatorType];

         $where = [
             'channel_id' => $channelId,
             'type' => $type,
             'operator_type' => $operatorType,
             'is_del' => 1,
         ];

         $log = $where;
         if($status == 1){//全选

             //获取全部地区
             $cityList = $areaDao->getList(['level_type'=>2], ['id', 'parent_id']);
             if(empty($cityList)){
                 throw new BusinessException(ErrorCode::ERR_BUESSUS, '未配置地区');
             }

             //渠道支持类型
             $channelAreaInfo = $channelAreaDao->findByWhere(['channel_id'=>$channelId,'type' => $type,'is_del' => 1]);

             //查询已存在地区
             $channelCityList = $channelAreaDao->findByWhere($where, ['city_id', 'province_id']);
             $channelAreaInfo = json_decode(json_encode($channelAreaInfo), true);
             $channelCityList = json_decode(json_encode($channelCityList), true);

             $channelCityList = empty($channelCityList) ? [] : array_column($channelCityList, 'province_id', 'city_id');
             $cityList = array_column($cityList, 'parent_id', 'id');

             //获取需要新增的渠道地区
             $resultCityList = array_diff_assoc($cityList, $channelCityList);
             //新增地区
             foreach ($resultCityList as $key => $value){
                 $where['city_id'] = (int)$key;
                 $where['province_id'] = $value;
                 $channelAreaDao->add($where);
             }

             if(!$channelAreaInfo && $info['type'] + $type < 4){
                 $channelDao->updateById($channelId, ['type'=>$info['type'] + $type]);
                 ServerUtil::info( '批量编辑渠道地区配置', [
                     'path'=>'/admin/channel_areaBatchAllEdit',
                     'parameter'=>['channel_id'=>$channelId,'status'=>$status,'where'=>$log],
                     'info'=> $info,
                 ]);
             }
             //添加管理员操作日记
             make(AdminLogDao::class)->addLog('渠道批量新增全国全部地区：'.json_encode($log));

         }else{//全不选
             $deleteStatus =  $channelAreaDao->del($where);
             //更新渠道支持类型
             if($deleteStatus && $info['type'] - $type >= 0 && !$channelAreaDao->findByWhere(['channel_id'=>$channelId,'type' => $type,'is_del' => 1])){
                 $channelDao->updateById($channelId, ['type'=>$info['type'] - $type]);
                 ServerUtil::info( '批量编辑渠道地区配置', [
                     'path'=>'/admin/channel_areaBatchAllEdit',
                     'parameter'=>['channel_id'=>$channelId,'status'=>$status,'where'=>$log],
                     'info'=> $info,
                 ]);
             }
             //添加管理员操作日记
             make(AdminLogDao::class)->addLog('渠道批量删除全国全部地区：'.json_encode($log));
         }

         return true;

     }

     /**
      * 获取渠道充值金额
      * @param $id
      * @return array
      */
     public function rechargeAmount($id)
     {
         $rechargeAmountChannelDao = make(RechargeAmountChannelDao::class);
         $info = make(ChannelDao::class)->findById($id, ['*'], true);
         if(empty($info)){
             throw new BusinessException(ErrorCode::ERR_BUESSUS, '渠道不存在');
         }

         $where = ['status' => 1];
         if($info['type'] != 3){
             $where['type_id'] = $info['type'];
         }
         $list = make(RechargeAmountDao::class)->searchByWhere($where,['id', 'type_id as type', 'ori_amount as amount']);
         if(empty($list)){
             throw new BusinessException(ErrorCode::ERR_BUESSUS, '请先配置充值面值');
         }
         foreach ($list as $k => $v){
             $cost = $rechargeAmountChannelDao->costByWhere(['recharge_amount_id'=>$v['id'], 'channel_id'=>$id]);
             $list[$k]['cost'] = $cost ? $cost : 0;
         }

         return ['type'=>$info['type'],'list'=>$list];
     }

     /**
      * 编辑渠道充值金额
      * @param $id
      * @param $rechargeAmount
      * @return bool
      */
     public function rechargeAmountEdit($id, $rechargeAmount)
     {
         $channelDao = make(ChannelDao::class);
         $rechargeAmountChannelDao = make(RechargeAmountChannelDao::class);

         $info = $channelDao->findById($id, ['*'], true);
         if(empty($info)){
             throw new BusinessException(ErrorCode::ERR_BUESSUS, '渠道不存在');
         }

         if($info['type'] == 0){
             throw new BusinessException(ErrorCode::ERR_BUESSUS, '请先配置渠道支持的充值类型');
         }

         $beforeList = $rechargeAmountChannelDao->searchByWhere(['channel_id'=>$id]);
         ServerUtil::info( '编辑渠道充值金额', [
             'path'=>'/admin/channel_rechargeAmount',
             'parameter'=>['id'=>$id,'recharge_amount'=>$rechargeAmount],
             'beforeList'=> $beforeList,
         ]);

         $insert = [];
         $insert['channel_id'] = $id;
         foreach ($rechargeAmount as $value) {
             if(empty($value['recharge_amount_id'])||empty($value['type'])||empty($value['cost'])){
                 throw new BusinessException(ErrorCode::ERR_BUESSUS, '渠道充值金额参数不完整');
             }
             $insert['recharge_amount_id'] = $value['recharge_amount_id'];
             $insert['type'] = $value['type'];
             if(!empty($rechargeAmountChannelDao->searchByWhere($insert, ['id']))){
                 $rechargeAmountChannelDao->update($insert, ['cost'=>$value['cost']]);
             }else{
                 $insert['cost'] = $value['cost'];
                 $rechargeAmountChannelDao->add($insert);
                 unset($insert['cost']);
             }
         }

         $list = $rechargeAmountChannelDao->searchByWhere(['channel_id'=>$id]);
         make(AdminLogDao::class)->addLog('编辑渠道成本备注：编辑前：'.json_encode($beforeList).'  编辑后：'.json_encode($list));
         return true;
     }

     /**
      * 面值获取支持某地区的渠道信息
      * @param $type
      * @param $operatorType
      * @param $cityId
      * @param $amount
      * @return bool|\Hyperf\Database\Model\Builder|\Hyperf\Database\Model\Model|object|null
      */
     public function amountByChannelInfo($type, $operatorType, $cityId, $amount){

         //获取充值面值id
         $rechargeAmountId = make(RechargeAmountDao::class)->isLegalAmount($amount, $type);
         if(empty($rechargeAmountId)){
             throw new BusinessException(ErrorCode::ERR_BUESSUS, '充值面值不支持');
         }

         return make(ChannelAreaDao::class)->findChannelByAmountArea($type, $operatorType, $cityId, $rechargeAmountId);

     }

     /**
      * 根据商户号获取渠道信息
      * @param $merchantNo
      * @return \Hyperf\Database\Model\Builder|\Hyperf\Database\Model\Model|object|null
      */
     public function merchantNoByChannelInfo($merchantNo){
         return make(ChannelDao::class)->merchantNoByChannelInfo($merchantNo);
     }

 }